home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb / dist / remote-multi.shar / remote_inflow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-20  |  9.0 KB  |  368 lines

  1. /* Low level interface to ptrace, for GDB when running under Unix.
  2.    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
  3. */
  4.  
  5. #include "defs.h"
  6. #include "param.h"
  7. #include "wait.h"
  8. #include "frame.h"
  9. #include "inferior.h"
  10. /***************************
  11. #include "initialize.h"
  12. ****************************/ 
  13.  
  14. #include <stdio.h>
  15. #include <sys/param.h>
  16. #include <sys/dir.h>
  17. #include <sys/user.h>
  18. #include <signal.h>
  19. #include <sys/ioctl.h>
  20. #include <sgtty.h>
  21. #include <fcntl.h>
  22.  
  23. /***************Begin MY defs*********************/ 
  24. int quit_flag = 0; 
  25. char registers[REGISTER_BYTES]; 
  26.  
  27. /* Index within `registers' of the first byte of the space for
  28.    register N.  */
  29.  
  30.  
  31. char buf2[MAX_REGISTER_RAW_SIZE];
  32. /***************End MY defs*********************/ 
  33.  
  34. #ifdef NEW_SUN_PTRACE
  35. #include <sys/ptrace.h>
  36. #include <machine/reg.h>
  37. #endif
  38.  
  39. extern char **environ; 
  40. extern int errno;
  41. extern int inferior_pid; 
  42. void error(), quit(), perror_with_name();
  43. int query(); 
  44. void supply_register(), write_register(); 
  45. CORE_ADDR read_register(); 
  46.  
  47. /* Nonzero if we are debugging an attached outside process
  48.    rather than an inferior.  */
  49.  
  50.  
  51. /* Start an inferior process and returns its pid.
  52.    ALLARGS is a vector of program-name and args.
  53.    ENV is the environment vector to pass.  */
  54.  
  55. int
  56. create_inferior (allargs, env)
  57.      char **allargs;
  58.      char **env;
  59. {
  60.   int pid;
  61.   extern int sys_nerr;
  62.   extern char *sys_errlist[];
  63.   extern int errno;
  64.  
  65.   /* exec is said to fail if the executable is open.  */
  66.   /****************close_exec_file ();*****************/ 
  67.  
  68.   pid = vfork ();
  69.   if (pid < 0)
  70.     perror_with_name ("vfork");
  71.  
  72.   if (pid == 0)
  73.     {
  74.       /* Run inferior in a separate process group.  */
  75.       setpgrp (getpid (), getpid ());
  76.  
  77. /* Not needed on Sun, at least, and loses there
  78.    because it clobbers the superior.  */
  79. /*???      signal (SIGQUIT, SIG_DFL);
  80.       signal (SIGINT, SIG_DFL);  */
  81.  
  82.       errno = 0; 
  83.       ptrace (0);
  84.  
  85.       execle ("/bin/sh", "sh", "-c", allargs, 0, env);
  86.  
  87.       fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
  88.            errno < sys_nerr ? sys_errlist[errno] : "unknown error");
  89.       fflush (stderr);
  90.       _exit (0177);
  91.     }
  92.   return pid;
  93. }
  94.  
  95. /* Kill the inferior process.  Make us have no inferior.  */
  96.  
  97. kill_inferior ()
  98. {
  99.   if (inferior_pid == 0)
  100.     return;
  101.   ptrace (8, inferior_pid, 0, 0);
  102.   wait (0);
  103.   /*************inferior_died ();****VK**************/ 
  104. }
  105.  
  106. /* Resume execution of the inferior process.
  107.    If STEP is nonzero, single-step it.
  108.    If SIGNAL is nonzero, give it that signal.  */
  109.  
  110. unsigned char
  111. resume (step, signal,status)
  112.      int step;
  113.      int signal;
  114.      char *status; 
  115. {
  116.     int pid ; 
  117.     WAITTYPE w; 
  118.  
  119.       errno = 0;
  120.     ptrace (step ? 9 : 7, inferior_pid, 1, signal);
  121.     if (errno)
  122.         perror_with_name ("ptrace");
  123.     pid = wait(&w); 
  124.     if(pid != inferior_pid) 
  125.         perror_with_name ("wait"); 
  126.  
  127.     if(WIFEXITED(w))
  128.     {
  129.         printf("\nchild exited with retcode = %x \n",WRETCODE(w)); 
  130.         *status = 'E'; 
  131.         return((unsigned char) WRETCODE(w));
  132.     } 
  133.     else if(!WIFSTOPPED(w))
  134.     {
  135.         printf("\nchild did terminated with signal = %x \n",WTERMSIG(w)); 
  136.         *status = 'T'; 
  137.         return((unsigned char) WTERMSIG(w)); 
  138.     } 
  139.     else 
  140.     {
  141.         printf("\nchild stopped with signal = %x \n",WSTOPSIG(w)); 
  142.         *status = 'S'; 
  143.         return((unsigned char) WSTOPSIG(w)); 
  144.     } 
  145.          
  146. }
  147.  
  148.  
  149. #ifdef NEW_SUN_PTRACE
  150.  
  151. void
  152. fetch_inferior_registers ()
  153. {
  154.   struct regs inferior_registers;
  155.   struct fp_status inferior_fp_registers;
  156.   extern char registers[];
  157.  
  158.       ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
  159.       if (errno)
  160.         perror_with_name ("ptrace");
  161.       /**********debugging begin **********/ 
  162.       print_some_registers(&inferior_registers); 
  163.       /**********debugging end **********/ 
  164.       ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
  165.       if (errno)
  166.         perror_with_name ("ptrace");
  167.  
  168.       bcopy (&inferior_registers, registers, 16 * 4);
  169.       bcopy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)],
  170.          sizeof inferior_fp_registers.fps_regs);
  171.       *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
  172.       *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
  173.       bcopy (&inferior_fp_registers.fps_control,
  174.          ®isters[REGISTER_BYTE (FPC_REGNUM)],
  175.          sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
  176. }
  177.  
  178. /* Store our register values back into the inferior.
  179.    If REGNO is -1, do this for all registers.
  180.    Otherwise, REGNO specifies which register (so we can save time).  */
  181.  
  182. store_inferior_registers (regno)
  183.      int regno;
  184. {
  185.   struct regs inferior_registers;
  186.   struct fp_status inferior_fp_registers;
  187.   extern char registers[];
  188.  
  189.       bcopy (registers, &inferior_registers, 16 * 4);
  190.       bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
  191.          sizeof inferior_fp_registers.fps_regs);
  192.       inferior_registers.r_ps = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)];
  193.       inferior_registers.r_pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)];
  194.       bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)],
  195.          &inferior_fp_registers.fps_control,
  196.          sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
  197.  
  198.       ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
  199.       if (errno)
  200.         perror_with_name ("ptrace");
  201.       ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
  202.       if (errno)
  203.         perror_with_name ("ptrace");
  204. }
  205.  
  206. #endif /* not NEW_SUN_PTRACE */
  207.  
  208.  
  209. /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
  210.    in the NEW_SUN_PTRACE case.
  211.    It ought to be straightforward.  But it appears that writing did
  212.    not write the data that I specified.  I cannot understand where
  213.    it got the data that it actually did write.  */
  214.  
  215. /* Copy LEN bytes from inferior's memory starting at MEMADDR
  216.    to debugger memory starting at MYADDR.  */
  217.  
  218. read_inferior_memory (memaddr, myaddr, len)
  219.      CORE_ADDR memaddr;
  220.      char *myaddr;
  221.      int len;
  222. {
  223.   register int i;
  224.   /* Round starting address down to longword boundary.  */
  225.   register CORE_ADDR addr = memaddr & - sizeof (int);
  226.   /* Round ending address up; get number of longwords that makes.  */
  227.   register int count
  228.     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  229.   /* Allocate buffer of that many longwords.  */
  230.   register int *buffer = (int *) alloca (count * sizeof (int));
  231.  
  232.   /* Read all the longwords */
  233.   for (i = 0; i < count; i++, addr += sizeof (int))
  234.     {
  235.     buffer[i] = ptrace (1, inferior_pid, addr, 0);
  236.     }
  237.  
  238.   /* Copy appropriate bytes out of the buffer.  */
  239.   bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
  240. }
  241.  
  242. /* Copy LEN bytes of data from debugger memory at MYADDR
  243.    to inferior's memory at MEMADDR.
  244.    On failure (cannot write the inferior)
  245.    returns the value of errno.  */
  246.  
  247. int
  248. write_inferior_memory (memaddr, myaddr, len)
  249.      CORE_ADDR memaddr;
  250.      char *myaddr;
  251.      int len;
  252. {
  253.   register int i;
  254.   /* Round starting address down to longword boundary.  */
  255.   register CORE_ADDR addr = memaddr & - sizeof (int);
  256.   /* Round ending address up; get number of longwords that makes.  */
  257.   register int count
  258.     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  259.   /* Allocate buffer of that many longwords.  */
  260.   register int *buffer = (int *) alloca (count * sizeof (int));
  261.   extern int errno;
  262.  
  263.   /* Fill start and end extra bytes of buffer with existing memory data.  */
  264.  
  265.     buffer[0] = ptrace (1, inferior_pid, addr, 0);
  266.  
  267.   if (count > 1)
  268.     {
  269.     buffer[count - 1]
  270.       = ptrace (1, inferior_pid,
  271.             addr + (count - 1) * sizeof (int), 0);
  272.     }
  273.  
  274.   /* Copy data to be written over corresponding part of buffer */
  275.  
  276.   bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
  277.  
  278.   /* Write the entire buffer.  */
  279.  
  280.   for (i = 0; i < count; i++, addr += sizeof (int))
  281.     {
  282.       errno = 0;
  283.     ptrace (4, inferior_pid, addr, buffer[i]);
  284.       if (errno)
  285.     return errno;
  286.     }
  287.  
  288.   return 0;
  289. }
  290.  
  291. void
  292. try_writing_regs_command ()
  293. {
  294.   register int i;
  295.   register int value;
  296.   extern int errno;
  297.  
  298.   if (inferior_pid == 0)
  299.     error ("There is no inferior process now.");
  300.  
  301.   fetch_inferior_registers(); 
  302.   for (i = 0;i<18 ; i ++)
  303.     {
  304.       QUIT;
  305.       errno = 0;
  306.       value = read_register(i); 
  307.       write_register ( i, value);
  308.       if (errno == 0)
  309.     {
  310.           printf (" Succeeded with register %d; value 0x%x (%d).\n",
  311.           i, value, value);
  312.     }
  313.       else 
  314.         printf (" Failed with register %d.\n", i);
  315.     }
  316. }
  317.  
  318. void
  319. initialize ()
  320. {
  321.  
  322.   inferior_pid = 0;
  323.  
  324.  
  325. }
  326.  
  327.  
  328. /* Return the contents of register REGNO,
  329.    regarding it as an integer.  */
  330.  
  331. CORE_ADDR
  332. read_register (regno)
  333.      int regno;
  334. {
  335.   /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
  336.   return *(int *) ®isters[REGISTER_BYTE (regno)];
  337. }
  338.  
  339. /* Store VALUE in the register number REGNO, regarded as an integer.  */
  340.  
  341. void
  342. write_register (regno, val)
  343.      int regno, val;
  344. {
  345.   /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
  346.   *(int *) ®isters[REGISTER_BYTE (regno)] = val;
  347.  
  348.   if (have_inferior_p ())
  349.     store_inferior_registers (regno);
  350. }
  351.  
  352.  
  353. int
  354. have_inferior_p ()
  355. {
  356.   return inferior_pid != 0;
  357. }
  358.  
  359. print_some_registers(regs)
  360. int regs[];
  361. {
  362.    register int i;
  363.    for (i = 0; i < 18; i++) {
  364.      printf("reg[%d] = %x\n", i, regs[i]);
  365.      }
  366. }
  367.  
  368.